x86: Add VGCF_onlien flag to vcpu_guest_context.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 12 Mar 2007 13:53:43 +0000 (13:53 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 12 Mar 2007 13:53:43 +0000 (13:53 +0000)
Change common Xen code to start all VCPUs (except idle ones)
offline. Change arch code to deal with this.
Signed-off-by: Keir Fraser <keir@xensource.com>
12 files changed:
tools/libxc/xc_dom_x86.c
tools/libxc/xc_hvm_build.c
tools/libxc/xc_linux_restore.c
xen/arch/ia64/xen/domain.c
xen/arch/powerpc/domain.c
xen/arch/powerpc/domain_build.c
xen/arch/x86/domain.c
xen/arch/x86/domain_build.c
xen/common/domain.c
xen/common/domctl.c
xen/include/public/arch-x86/xen.h
xen/include/public/foreign/structs.py

index 19296daf10d0afe9f8c7d00e7686ba1c8c458707..a5087751409e24f8f415b933dee268a753b3db8d 100644 (file)
@@ -455,7 +455,7 @@ static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
     ctxt->kernel_ss = ctxt->user_regs.ss;
     ctxt->kernel_sp = ctxt->user_regs.esp;
 
-    ctxt->flags = VGCF_in_kernel_X86_32;
+    ctxt->flags = VGCF_in_kernel_X86_32 | VGCF_online_X86_32;
     if ( dom->parms.pae == 2 /* extended_cr3 */ ||
          dom->parms.pae == 3 /* bimodal */ )
         ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
@@ -494,7 +494,7 @@ static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
     ctxt->kernel_ss = ctxt->user_regs.ss;
     ctxt->kernel_sp = ctxt->user_regs.esp;
 
-    ctxt->flags = VGCF_in_kernel_X86_64;
+    ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64;
     cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
     ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn);
     xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n",
index 2238d315bc434441099adb74e000331319cc44a6..00f46245016fb4f6cec78b4676201a62fb036e30 100644 (file)
@@ -302,9 +302,15 @@ static int setup_guest(int xc_handle,
 
     /* Set [er]ip in the way that's right for Xen */
     if ( strstr(caps, "x86_64") )
+    {
         ctxt->c64.user_regs.rip = elf_uval(&elf, elf.ehdr, e_entry); 
+        ctxt->c64.flags = VGCF_online;
+    }
     else
+    {
         ctxt->c32.user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry);
+        ctxt->c32.flags = VGCF_online;
+    }
 
     return 0;
 
@@ -344,7 +350,7 @@ static int xc_hvm_build_internal(int xc_handle,
 
     memset(&launch_domctl, 0, sizeof(launch_domctl));
     launch_domctl.domain = (domid_t)domid;
-    launch_domctl.u.vcpucontext.vcpu   = 0;
+    launch_domctl.u.vcpucontext.vcpu = 0;
     set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt.c);
     launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
     rc = xc_domctl(xc_handle, &launch_domctl);
index 6fa0388d3f5e0ba57b7cc43ad256c9c97b8e3855..d3a87262a0339a902826fbd9c5ecb3cf7895963e 100644 (file)
@@ -189,6 +189,7 @@ int xc_linux_restore(int xc_handle, int io_fd,
 
     uint64_t vcpumap = 1ULL;
     unsigned int max_vcpu_id = 0;
+    int new_ctxt_format = 0;
 
     max_pfn = nr_pfns;
 
@@ -372,6 +373,7 @@ int xc_linux_restore(int xc_handle, int io_fd,
         }
 
         if (j == -2) {
+            new_ctxt_format = 1;
             if (!read_exact(io_fd, &max_vcpu_id, sizeof(int)) ||
                 (max_vcpu_id >= 64) ||
                 !read_exact(io_fd, &vcpumap, sizeof(uint64_t))) {
@@ -797,6 +799,9 @@ int xc_linux_restore(int xc_handle, int io_fd,
             goto out;
         }
 
+        if ( !new_ctxt_format )
+            ctxt.flags |= VGCF_online;
+
         if (i == 0) {
             /*
              * Uncanonicalise the suspend-record frame number and poke
index 631d8dfa094f724d48c902f25ab1452a05fe30a7..2bb2ef8172065061197a49f82f20362fd06cde1e 100644 (file)
@@ -672,8 +672,11 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
        /* This overrides some registers. */
        vcpu_init_regs(v);
 
-       /* Don't redo final setup */
-       set_bit(_VCPUF_initialised, &v->vcpu_flags);
+       /* Don't redo final setup. Auto-online VCPU0. */
+       if (!test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
+           (v->vcpu_id == 0))
+               clear_bit(_VCPUF_down, &v->vcpu_flags);
+
        return 0;
 }
 
@@ -1182,6 +1185,7 @@ int construct_dom0(struct domain *d,
        printk("Dom0: 0x%lx\n", (u64)dom0);
 
        set_bit(_VCPUF_initialised, &v->vcpu_flags);
+       clear_bit(_VCPUF_down, &v->vcpu_flags);
 
        /* Build firmware.
           Note: Linux kernel reserve memory used by start_info, so there is
index 156b70ffd9f4128ad24b6d386aea8f58d80ee6c5..1ecf35a666adbf34cd35d90240a240f511f97405 100644 (file)
@@ -168,7 +168,10 @@ int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     d->shared_info->wc_nsec = dom0->shared_info->wc_nsec;
     d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase;
 
-    set_bit(_VCPUF_initialised, &v->vcpu_flags);
+    /* Auto-online VCPU0 when it is initialised. */
+    if ( !test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
+         (v->vcpu_id == 0) )
+        clear_bit(_VCPUF_down, &v->vcpu_flags);
 
     cpu_init_vcpu(v);
 
index 08d53ff9dc5d8e3ad54bbcf2fa5123b133155b69..af7ad3db4516e309795011230de10140db810ffa 100644 (file)
@@ -274,6 +274,7 @@ int construct_dom0(struct domain *d,
     ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
 
     set_bit(_VCPUF_initialised, &v->vcpu_flags);
+    clear_bit(_VCPUF_down, &v->vcpu_flags);
 
     rc = 0;
 
index 2d6bdca72c6c324055f9a979aa86e137e1b847d2..ca82c12590bff86dba928cfd1438b208fab0814b 100644 (file)
@@ -601,7 +601,7 @@ int arch_set_info_guest(
     }
 
     if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
-        return 0;
+        goto out;
 
     memset(v->arch.guest_context.debugreg, 0,
            sizeof(v->arch.guest_context.debugreg));
@@ -706,6 +706,11 @@ int arch_set_info_guest(
 
     update_cr3(v);
 
+ out:
+    if ( flags & VGCF_online )
+        clear_bit(_VCPUF_down, &v->vcpu_flags);
+    else
+        set_bit(_VCPUF_down, &v->vcpu_flags);
     return 0;
 #undef c
 }
index 5d7941ab5dfeb8b57264f5e33f46442140ec7222..96215da601a3d8333e6ed9f1f5301b52f68a17bd 100644 (file)
@@ -902,6 +902,7 @@ int construct_dom0(struct domain *d,
     update_domain_wallclock_time(d);
 
     set_bit(_VCPUF_initialised, &v->vcpu_flags);
+    clear_bit(_VCPUF_down, &v->vcpu_flags);
 
     /*
      * Initial register values:
index 57fb9ade71858bb22b1a1da7a3281521c7761c26..3008a4cc9050e3683914f4990e72eb5a08dae53e 100644 (file)
@@ -102,7 +102,7 @@ struct vcpu *alloc_vcpu(
     v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
     v->runstate.state_entry_time = NOW();
 
-    if ( (vcpu_id != 0) && !is_idle_domain(d) )
+    if ( !is_idle_domain(d) )
         set_bit(_VCPUF_down, &v->vcpu_flags);
 
     if ( sched_init_vcpu(v, cpu_id) != 0 )
index 3a45586d65c1d9a08fdf6204b68df16b2297f5b4..6f2f351895516713db860e06aee0026a81a4558c 100644 (file)
@@ -268,18 +268,14 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
     case XEN_DOMCTL_unpausedomain:
     {
         struct domain *d = rcu_lock_domain_by_id(op->domain);
+
         ret = -ESRCH;
-        if ( d != NULL )
-        {
-            ret = -EINVAL;
-            if ( (d != current->domain) && (d->vcpu[0] != NULL) &&
-                 test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
-            {
-                domain_unpause_by_systemcontroller(d);
-                ret = 0;
-            }
-            rcu_unlock_domain(d);
-        }
+        if ( d == NULL )
+            break;
+
+        domain_unpause_by_systemcontroller(d);
+        rcu_unlock_domain(d);
+        ret = 0;
     }
     break;
 
index f927130058735aa958765a51ea2f091d8522c903..9fe0b7620474e4c1d8c315fc33b1a76dbb40400f 100644 (file)
@@ -126,6 +126,8 @@ struct vcpu_guest_context {
 #define VGCF_failsafe_disables_events  (1<<_VGCF_failsafe_disables_events)
 #define _VGCF_syscall_disables_events  4
 #define VGCF_syscall_disables_events   (1<<_VGCF_syscall_disables_events)
+#define _VGCF_online                   5
+#define VGCF_online                    (1<<_VGCF_online)
     unsigned long flags;                    /* VGCF_* flags                 */
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
     struct trap_info trap_ctxt[256];        /* Virtual IDT                  */
index 79eeab3b8e92f5a60d8d2ae893e12e365889b26f..6ecd1aa3ddce6e4c10f5413cc9f99cb632f287ce 100644 (file)
@@ -41,6 +41,8 @@ defines = [ "__i386__",
             "VGCF_failsafe_disables_events",
             "_VGCF_syscall_disables_events",
             "VGCF_syscall_disables_events",
+            "_VGCF_online",
+            "VGCF_online",
 
             # ia64
             "VGCF_EXTRA_REGS",